#ifndef SM2_H
#define SM2_H

#include "common_func.h"
#include <stdint.h>

#define SM2_BASEADDR 			0xbf100200

#define SM2_ECC_START 			 SM2_BASEADDR
#define SM2_ECC_DONE 			(SM2_BASEADDR + 0x04)
#define SM2_ECC_FUNC_SELECT		(SM2_BASEADDR + 0x08)
#define SM2_ECC_CURVE_SELECT	(SM2_BASEADDR + 0x0c)
#define SM2_PRIVATE_KEY_0		(SM2_BASEADDR + 0x10)
#define SM2_PRIVATE_KEY_1		(SM2_BASEADDR + 0x14)
#define SM2_PRIVATE_KEY_2		(SM2_BASEADDR + 0x18)
#define SM2_PRIVATE_KEY_3		(SM2_BASEADDR + 0x1c)
#define SM2_PRIVATE_KEY_4		(SM2_BASEADDR + 0x20)
#define SM2_PRIVATE_KEY_5		(SM2_BASEADDR + 0x24)
#define SM2_PRIVATE_KEY_6		(SM2_BASEADDR + 0x28)
#define SM2_PRIVATE_KEY_7		(SM2_BASEADDR + 0x2c)
#define SM2_PUBKEY_X_0			(SM2_BASEADDR + 0x30)
#define SM2_PUBKEY_X_1			(SM2_BASEADDR + 0x34)
#define SM2_PUBKEY_X_2			(SM2_BASEADDR + 0x38)
#define SM2_PUBKEY_X_3			(SM2_BASEADDR + 0x3c)
#define SM2_PUBKEY_X_4			(SM2_BASEADDR + 0x40)
#define SM2_PUBKEY_X_5			(SM2_BASEADDR + 0x44)
#define SM2_PUBKEY_X_6			(SM2_BASEADDR + 0x48)
#define SM2_PUBKEY_X_7			(SM2_BASEADDR + 0x4c)
#define SM2_PUBKEY_Y_0			(SM2_BASEADDR + 0x50)
#define SM2_PUBKEY_Y_1			(SM2_BASEADDR + 0x54)
#define SM2_PUBKEY_Y_2			(SM2_BASEADDR + 0x58)
#define SM2_PUBKEY_Y_3			(SM2_BASEADDR + 0x5c)
#define SM2_PUBKEY_Y_4			(SM2_BASEADDR + 0x60)
#define SM2_PUBKEY_Y_5			(SM2_BASEADDR + 0x64)
#define SM2_PUBKEY_Y_6			(SM2_BASEADDR + 0x68)
#define SM2_PUBKEY_Y_7			(SM2_BASEADDR + 0x6c)
#define SM2_K_RANDOM_0			(SM2_BASEADDR + 0x70)
#define SM2_K_RANDOM_1			(SM2_BASEADDR + 0x74)
#define SM2_K_RANDOM_2			(SM2_BASEADDR + 0x78)
#define SM2_K_RANDOM_3			(SM2_BASEADDR + 0x7c)
#define SM2_K_RANDOM_4			(SM2_BASEADDR + 0x80)
#define SM2_K_RANDOM_5			(SM2_BASEADDR + 0x84)
#define SM2_K_RANDOM_6			(SM2_BASEADDR + 0x88)
#define SM2_K_RANDOM_7			(SM2_BASEADDR + 0x8c)
#define SM2_SIGNATURE_S_0		(SM2_BASEADDR + 0x90)
#define SM2_SIGNATURE_S_1		(SM2_BASEADDR + 0x94)
#define SM2_SIGNATURE_S_2		(SM2_BASEADDR + 0x98)
#define SM2_SIGNATURE_S_3		(SM2_BASEADDR + 0x9c)
#define SM2_SIGNATURE_S_4		(SM2_BASEADDR + 0xa0)
#define SM2_SIGNATURE_S_5		(SM2_BASEADDR + 0xa4)
#define SM2_SIGNATURE_S_6		(SM2_BASEADDR + 0xa8)
#define SM2_SIGNATURE_S_7		(SM2_BASEADDR + 0xac)
#define SM2_SIGNATURE_R_0		(SM2_BASEADDR + 0xb0)
#define SM2_SIGNATURE_R_1		(SM2_BASEADDR + 0xb4)
#define SM2_SIGNATURE_R_2		(SM2_BASEADDR + 0xb8)
#define SM2_SIGNATURE_R_3		(SM2_BASEADDR + 0xbc)
#define SM2_SIGNATURE_R_4		(SM2_BASEADDR + 0xc0)
#define SM2_SIGNATURE_R_5		(SM2_BASEADDR + 0xc4)
#define SM2_SIGNATURE_R_6		(SM2_BASEADDR + 0xc8)
#define SM2_SIGNATURE_R_7		(SM2_BASEADDR + 0xcc)
#define SM2_HASH_DONE			(SM2_BASEADDR + 0xd0)
#define SM2_HASH_RESULT_0		(SM2_BASEADDR + 0xd4)
#define SM2_HASH_RESULT_1		(SM2_BASEADDR + 0xd8)
#define SM2_HASH_RESULT_2		(SM2_BASEADDR + 0xdc)
#define SM2_HASH_RESULT_3		(SM2_BASEADDR + 0xe0)
#define SM2_HASH_RESULT_4		(SM2_BASEADDR + 0xe4)
#define SM2_HASH_RESULT_5		(SM2_BASEADDR + 0xe8)
#define SM2_HASH_RESULT_6		(SM2_BASEADDR + 0xec)
#define SM2_HASH_RESULT_7		(SM2_BASEADDR + 0xf0)
#define SM2_VERIFY_OK			(SM2_BASEADDR + 0xf4)
#define SM2_ECC_STATE			(SM2_BASEADDR + 0xf8)
#define SM2_ERROR_CODE			(SM2_BASEADDR + 0xfc)
#define SM2_RESULT_S_0			(SM2_BASEADDR + 0x100)
#define SM2_RESULT_S_1			(SM2_BASEADDR + 0x104)
#define SM2_RESULT_S_2			(SM2_BASEADDR + 0x108)
#define SM2_RESULT_S_3			(SM2_BASEADDR + 0x10c)
#define SM2_RESULT_S_4			(SM2_BASEADDR + 0x110)
#define SM2_RESULT_S_5			(SM2_BASEADDR + 0x114)
#define SM2_RESULT_S_6			(SM2_BASEADDR + 0x118)
#define SM2_RESULT_S_7			(SM2_BASEADDR + 0x11c)
#define SM2_RESULT_R_0			(SM2_BASEADDR + 0x120)
#define SM2_RESULT_R_1			(SM2_BASEADDR + 0x124)
#define SM2_RESULT_R_2			(SM2_BASEADDR + 0x128)
#define SM2_RESULT_R_3			(SM2_BASEADDR + 0x12c)
#define SM2_RESULT_R_4			(SM2_BASEADDR + 0x130)
#define SM2_RESULT_R_5			(SM2_BASEADDR + 0x134)
#define SM2_RESULT_R_6			(SM2_BASEADDR + 0x138)
#define SM2_RESULT_R_7			(SM2_BASEADDR + 0x13c)
#define SM2_ENABLE_INT			(SM2_BASEADDR + 0x140)

#define SM2_WAIT_TIME		0x01


typedef struct ECCrefPublicKey_st {           
    uint32_t x[8];
    uint32_t y[8];
}ECCrefPublicKey;

typedef struct ECCrefPrivateKey_st {
    uint32_t K[8];
}ECCrefPrivateKey;

typedef struct ECCSignature_st {
    uint32_t r[8];
    uint32_t s[8];
}ECCSignature;


uint32_t sm2_signature(ECCrefPrivateKey *prikey, uint32_t *random_k, uint32_t *hash_data, ECCSignature *signature);
uint32_t sm2_verify(ECCrefPublicKey *pubkey, ECCSignature *signature, uint32_t *hash_data);
uint32_t sm2_signature_inkey(uint32_t *random_k, uint32_t *hash_data, ECCSignature *signature);
uint32_t sm2_verify_inkey(ECCSignature *signature, uint32_t *hash_data);
uint32_t sm2_verify_callback(void);
uint32_t sm2_verify_int(ECCrefPublicKey *pubkey, ECCSignature *signature, uint32_t *hash_data);
uint32_t sm2_signature_int(ECCrefPrivateKey *prikey, uint32_t *random_k, uint32_t *hash_data);
uint32_t sm2_verify_int_inkey(ECCSignature *signature, uint32_t *hash_data);
uint32_t sm2_signature_int_inkey(uint32_t *random_k, uint32_t *hash_data);
uint32_t sm2_signature_callback(ECCSignature *signature);

#endif 
